package textExcel;

public class MethodCell extends Cell
{
	private final String[] parts;
	private final Spreadsheet spreadsheet;
	
	public MethodCell(String method, Spreadsheet spreadsheet)
	{
		this.parts = split(method, spreadsheet);

		if (this.parts == null) // split returns null for invalid methods
			throw new IllegalArgumentException("Invalid method");

		this.spreadsheet = spreadsheet;
	}
	
	public boolean hasNumericValue()
	{
		return true;
	}
    
    public double numericValue()
    {
    	// TODO: handle longer column names (ex: AA)
    	
    	double sum = 0;
    	int count = 0;
    	
    	int firstColumn = (int) parts[2].charAt(0);
    	int lastColumn = (int) parts[3].charAt(0);
    	
    	int firstRow = Integer.parseInt(parts[2].substring(1));
    	int lastRow = Integer.parseInt(parts[3].substring(1));
    	
    	for(int column = firstColumn; column <= lastColumn; column++)
    	{
    		for(int row = firstRow; row <= lastRow; row++)
    		{
    			Cell numericCell = this.spreadsheet.getCell((char) column, row);
    			
    			if(! numericCell.hasNumericValue() )
    				throw new IllegalStateException("Referenced cell does not contain a numeric value");
    			
    			double cellValue = numericCell.numericValue();
    			
    			sum += cellValue;
    			count++;
    		}
    	}
    	
    	switch(this.parts[1])
    	{
    	case "SUM":
    		return sum;
    		
    	case "AVG":
    		return sum / count;
    	}
    	
    	throw new IllegalStateException("Command is invalid");
    }
    
    public static boolean isValidMethod(String method, Spreadsheet spreadsheet)
    {
    	return split(method, spreadsheet) != null;
    }
    
    // returns null if method is invalid
    private static String[] split(String method, Spreadsheet spreadsheet)
    {
    	// TODO: guaranteed spaces before and after parentheses or no?
    	
    	String[] parts = method.split("[ -]");
    	
    	if(parts.length != 5 ||
    			! "(".equals(parts[0]) || ! ")".equals(parts[parts.length - 1]))
    		return null;
    	
    	parts[1] = parts[1].toUpperCase();
    	
		switch (parts[1])
		{
		case "SUM":
		case "AVG":
			break;

		default:
			return null;
		}
		
		if(!spreadsheet.isValidNumericRange(parts[2], parts[3]))
			return null;
		
		return parts;
    }
}
